package cate.game.role.res.leader.hallows;

import cate.common.table.d.GD;
import cate.common.table.d.GDFunc;
import cate.common.table.d.GDHallows;
import cate.common.table.hallow.HallowHallucinateRow;
import cate.common.table.hallow.row.HallowBaseRow;
import cate.common.util.GameResult;
import cate.game.attr.FightAttr;
import cate.game.role.FuncOpenChecker;
import cate.game.role.Role;
import cate.game.role.res.leader.hallows.msg.HallowsDataResp;
import cate.game.role.task.TaskGroup;
import com.fasterxml.jackson.annotation.JsonIgnore;
import easy.java.dev.note.NoteClass;
import easy.java.dev.note.NoteField;
import easy.java.practice.errorcode.EcResult;

import java.util.*;

@NoteClass(value = "所有圣器的数据")
public class Hallows extends FuncOpenChecker {
  @NoteField(value = "圣器们")
  public List<Hallow> items;

  @NoteField(value = "第一个未解锁的圣器类型")
  public int firstLockType;

  @NoteField(value = "圣器任务们", detail = "<圣器,对应的任务>")
  public Map<Integer, List<Integer>> taskMap;

  @NoteField(value = "圣器幻化")
  public HallowsSkinPO skinPO;

  public Hallows() {
  }

  @Override
  public void initialize(Role role) {
    super.initialize(role);
    if (items == null) {
      items = new ArrayList<>();
    }
    items.forEach(e -> e.initialize(role));
    if (taskMap == null) {
      taskMap = new HashMap<>();
    }
    if (firstLockType == GD.INT_0) {
      firstLockType = 1;
    }
    if (skinPO == null) {
      skinPO = new HallowsSkinPO();
    }
    skinPO.initialize(role);
  }

  public void update() {
    TaskGroup group = role.getTask().getGroup(GDFunc.HALLOWS);
    List<Integer> taskIds = new ArrayList<>();
    List<HallowBaseRow> list = role.getGame().table.hallow.base.getList();
    for (HallowBaseRow baseRow : list) {
      taskMap.put(baseRow.id, baseRow.taskList);
      taskIds.addAll(baseRow.taskList);
    }
    group.addItemListNoRepeat(taskIds);
  }

  public void tick() {
    if(skinPO.checkTime<=0|| role.getGame().time.now()<skinPO.checkTime){
      return;
    }
    Iterator<Map.Entry<Integer, Long>> it = skinPO.skinMap.entrySet().iterator();
    boolean change = false;
    while (it.hasNext()) {
      Map.Entry<Integer, Long> next = it.next();
      if (next.getValue() <= System.currentTimeMillis()) {
        int skinId = next.getKey();
        for (Hallow item : items) {
          if (item.skinId == skinId) {
            item.skinId = GD.INT_0;
          }
        }
        change = true;
        it.remove();
      }
    }
    if (change) {
      skinPO.resetCheckTime();
      noticeUpdate();
    }
  }

  @Override
  public int getFuncId() {
    return GDFunc.HALLOWS;
  }

  @Override
  public void onAfterOpen() {
    noticeUpdate();
  }

  public Hallow getItem(int type) {
    return items.stream().filter(e -> e.type == type).findAny().orElse(null);
  }

  /**
   * 解锁圣器
   *
   * @param type 圣器类型
   */
  public void unlock(int type) {
    Hallow hallow = getItem(type);
    if (hallow != null) {
      role.getGame().notice.message(role, "已经激活过此圣器拉");
      return;
    }
    HallowBaseRow hallowBase = role.getGame().table.hallow.base.get(type);
    if (hallowBase == null) {
      role.getGame().notice.message(role, "圣器类型有误");
      return;
    }
    hallow = new Hallow(role, type);
    hallow.initialize(role);
    items.add(hallow);
    hallow.noticeUnlock();
    //解锁必涨战斗力
    role.getBase().updatePower();
    role.getHistory().action.unlockHallow();
    role.getHistory().action.hallowNum(items.size());
  }

  /**
   * 解锁圣器层级
   */
  public void unlockLevel() {
    noticeUpdate();
  }

  /**
   * 淬炼
   */
  public void quenching(int type) {
    Hallow hallow = getItem(type);
    if (hallow == null) {
      role.getGame().notice.message(role, "请前往食神之路 觉醒圣器");
      return;
    }
    EcResult<Boolean> res = hallow.quenching();
    if (!res.ok()) {
      role.getGame().notice.message(role, res.message);
      return;
    }
    role.getBase().updatePower();
    if (Boolean.TRUE.equals(res.data)) {
      role.getHistory().action.hallowGradeUp(items);
    }
  }

  /**
   * 选择升级的技能
   *
   * @param type 圣器类型
   */
  public void upgradeSkill(int type) {
    if (items.size() < taskMap.size()) {
      role.getGame().notice.message(role, "请先觉醒全部圣器");
      return;
    }
    Hallow hallow = getItem(type);
    GameResult res = hallow.upgradeSkill();
    if (!res.ok()) {
      role.getGame().notice.message(role, res);
      return;
    }
    role.getBase().updatePower();
  }


  public void noticeUpdate() {
    if (isOpen()) {
      role.sendNow(new HallowsDataResp(this));
    }
  }

  /**
   * 圣器的属性计算
   *
   * @param type type
   * @return attr
   */
  @JsonIgnore
  public FightAttr getAttr(int type) {
    FightAttr attr = new FightAttr();
    Hallow hallow = getItem(type);
    if (hallow == null) {
      return attr;
    }
    attr.add(hallow.getAttr(role.getGame()));
    if (hallow.deputyType == GD.INT_0) {
      return attr;
    }
    Hallow deputyHallow = getItem(hallow.deputyType);
    if (deputyHallow == null) {
      return attr;
    }
    attr.add(deputyHallow.getAttr(role.getGame()).scale(GDHallows.DEPUTY_HALLOW_SCALE));
    //幻化属性
    FightAttr s2Attr = new FightAttr();
    for (Integer skinId : skinPO.skinMap.keySet()) {
        HallowHallucinateRow hallucinateRow = role.getGame().table.hallow.hallucinate.get(skinId);
        if (hallucinateRow == null) {
          continue;
        }
        s2Attr.add(new FightAttr(hallucinateRow.attrStr));

    }
    if (!s2Attr.isEmpty()) {
      attr.addAndCalS2(s2Attr);
    }
    return attr;
  }

  public void gmResetAll() {
    items.forEach(Hallow::gmReset);
    noticeUpdate();
  }

  @Override
  public void onEnter() {
    update();
    items.forEach(Hallow::onEnter);
  }

  /**
   * 检测圣器任务是否全部完成领奖，开启圣器
   */
  public void checkHollowRelease() {
    TaskGroup group = role.getTask().getGroup(GDFunc.HALLOWS);
    List<Integer> list = taskMap.get(this.firstLockType);
    if (list == null) {
      return;
    }

    if (list.stream().allMatch(taskId -> group.getItem(taskId).rewardGot)) {
      this.unlock(this.firstLockType);
      this.firstLockType++;
      noticeUpdate();
    }
  }

  /**
   * 圣器圣印升级
   *
   * @param type type
   */
  public void upgradeHolySeal(int type) {
    if (items.size() < taskMap.size()) {
      role.getGame().notice.message(role, "请先觉醒全部圣器");
      return;
    }
    Hallow hallow = getItem(type);
    GameResult<Void> res = hallow.upgradeHolySeal();
    if (!res.ok()) {
      role.getGame().notice.message(role, res);
      return;
    }
    role.getBase().updatePower();
  }


  /**
   * 圣器精炼
   *
   * @param type type
   */
  public void refineSkill(int type) {
    if (items.size() < taskMap.size()) {
      role.getGame().notice.message(role, "请先觉醒全部圣器");
      return;
    }
    Hallow hallow = getItem(type);
    GameResult<Void> res = hallow.refineSkill();
    if (!res.ok()) {
      role.getGame().notice.message(role, res);
      return;
    } else {
      int level = items.stream().filter(e -> e.refineSkill != null).
              map(e -> e.refineSkill.level).max(Comparator.comparingInt(e -> e)).orElse(0);
      if (level > 0) {
        role.getHistory().action.hallowRefineLevel(level);
      }
    }
    role.getBase().updatePower();
  }

  public void hallucinate(int type, int skinId) {
    if (items.size() < taskMap.size()) {
      role.getGame().notice.message(role, "请先觉醒全部圣器");
      return;
    }
    if (!skinPO.isOpen()) {
      role.getGame().notice.message(role, "幻化功能未开启");
    }

    GameResult<Void> res = skinPO.hallucinate(type, skinId, this);
    if (!res.ok()) {
      role.getGame().notice.message(role, res.message);
      return;
    }
    role.getGame().notice.message(role, "幻化成功");
    role.getBase().updatePower();
    noticeUpdate();
  }

  public void setDeputyHallow(int type, int deputyType) {
    if (items.size() < taskMap.size()) {
      role.getGame().notice.message(role, "请先觉醒全部圣器");
      return;
    }
    Hallow hallow = getItem(type);
    GameResult<Void> res = hallow.setDeputyHallow(deputyType);
    if (!res.ok()) {
      role.getGame().notice.message(role, res.message);
    }
    role.getBase().updatePower();
  }

  /**
   * 圣器重铸
   *
   * @param type type
   */
  public void backHallows(int type) {
    if (items.size() < taskMap.size()) {
      role.getGame().notice.message(role, "请先觉醒全部圣器");
      return;
    }
    Hallow hallow = getItem(type);
    GameResult<Void> res = hallow.backHallow();
    if (!res.ok()) {
      role.getGame().notice.message(role, res.message);
    }
    role.getBase().updatePower();
  }

  public void activeSkin(int skinId) {
    skinPO.checkOpen();
    if (!skinPO.isOpen()) {
      role.getGame().notice.message(role, "幻化功能未开启");
      return;
    }
    GameResult result = skinPO.activeSkin( skinId);
    if (!result.ok()) {
      role.getGame().notice.message(role, result);
      return;
    }
    noticeUpdate();
  }


}
